package com.h3c.nem.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.eos.common.util.IdWorker;
import com.h3c.nem.async.AsyncSendMessage;
import com.h3c.nem.dto.TbOfferWorkerDTO;
import com.h3c.nem.entity.*;
import com.h3c.nem.enums.OfferModifyApprovalEnum;
import com.h3c.nem.enums.RequestEnum;
import com.h3c.nem.mapper.SdNoticeRecordMapper;
import com.h3c.nem.mapper.SdUserMapper;
import com.h3c.nem.sap.RfcManager;
import com.h3c.nem.service.*;
import com.h3c.nem.utils.AppBusinessException;
import com.h3c.nem.utils.BusiEnumDefine;
import com.h3c.nem.utils.DateUtil;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoFunction;
import com.sap.conn.jco.JCoParameterList;
import com.sap.conn.jco.JCoStructure;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * Copyright (C), 2020-2020, h3c
 * FileName: SdNoticeRecordServiceImpl
 *
 * @Author: l22886
 * @Date: 2022-01-19
 * Description: sd_notice_record serviceImpl
 * Version: 1.0
 */
@Slf4j
@Service
public class SdNoticeRecordServiceImpl extends ServiceImpl<SdNoticeRecordMapper, SdNoticeRecord> implements ISdNoticeRecordService {

    @Resource
    private CommService commService;
    @Resource
    private ISdDeptService iSdDeptService;
    @Resource
    private ISdUserService iSdUserService;
    @Resource
    private SdUserMapper sdUserMapper;
    @Resource
    private RfcManager rfcManager;
    @Resource
    private ISdEmailTemplateService emailTemplateService;
    @Resource
    private BeiSenService beiSenService;
    @Resource
    private AsyncSendMessage asyncSendMessage;
    @Resource
    private SdRequestRecordService sdRequestRecordService;
    @Value("${level.twelve.notice}")
    private String upTwelveNotice;
    @Value("${tech.notice}")
    private String techNotice;
    @Value("${market.notice}")
    private String marketNotice;
    @Value("${other.notice}")
    private String otherNotice;

    @Override
    public SdNoticeRecord createOfferModifyRecord(String flowId, String deptNameChain, String emailCode, Integer status) {
        return createOfferModifyRecord(flowId, deptNameChain, emailCode, status, "", null);
    }

    public SdNoticeRecord createOfferModifyRecord(String flowId, String deptNameChain, String emailCode, Integer status, String targetId, TbOfferWorkerDTO offerWorker) {
        String workerId = "";
        if (OfferModifyApprovalEnum.OFFER_MODIFY_APPROVAL_GBBZ.getStatus().equals(status)) {
            SdDept dept = iSdDeptService.getDeptByNameChain(deptNameChain);
            if (dept == null) {
                throw new AppBusinessException("部门没有找到");
            }
            workerId = getFirstUserId(dept.getGbbzId());
        } else if (OfferModifyApprovalEnum.OFFER_MODIFY_APPROVAL_MANAGER.getStatus().equals(status)) {
            String[] split = deptNameChain.split("/");
            String dept1Name = split[0];
            QueryWrapper<SdDept> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(SdDept::getDeptName, dept1Name).eq(SdDept::getDeptLevel, 1);
            SdDept dept1 = iSdDeptService.getOne(queryWrapper);
            if (dept1 == null) {
                throw new AppBusinessException("一级部门没有找到");
            }
            workerId = getFirstUserId(dept1.getDeptManagerId()); //一级主管
        } else if (OfferModifyApprovalEnum.OFFER_MODIFY_APPROVAL_RECRUITMENT.getStatus().equals(status)) {
//            QueryWrapper<SdUser> queryWrapper = new QueryWrapper<>();
//            queryWrapper.lambda().eq(SdUser::getUserRole, BusiEnumDefine.USER_ROLE_RECRUITMENT);
//            List<SdUser> roleList = sdUserMapper.selectList(queryWrapper);
//            if (!roleList.isEmpty()) {
//                SdUser sdUser = roleList.get(0);
//                workerId = sdUser.getUserId();
//            } else {
//                throw new AppBusinessException("没有找到招聘调配部管理员");
//            }
            String jobLevel = offerWorker.getJobLevel();
            if (!StringUtils.isEmpty(jobLevel) && Integer.parseInt(jobLevel) >= 12) {
                workerId = upTwelveNotice;
            } else {
                String deptSystem = offerWorker.getDeptSystem();
                if (BusiEnumDefine.TECH_SYSTEM.equals(deptSystem)) {
                    workerId = techNotice;
                } else if (BusiEnumDefine.MARKET_SYSTEM.equals(deptSystem)) {
                    workerId = marketNotice;
                } else {
                    workerId = otherNotice;
                }
            }
        } else if (OfferModifyApprovalEnum.OFFER_MODIFY_APPROVAL_CHRO.getStatus().equals(status)) {
            QueryWrapper<SdUser> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(SdUser::getUserRole, BusiEnumDefine.USER_ROLE_CHRO);
            List<SdUser> chroList = sdUserMapper.selectList(queryWrapper);
            if (!chroList.isEmpty()) {
                SdUser sdUser = chroList.get(0);
                workerId = sdUser.getUserId();
            } else {
                throw new AppBusinessException("没有找到CHRO");
            }
        } else {
            //转办
            workerId = targetId;
        }

        return createEntity(flowId, workerId, emailCode, "");
    }

    public String getFirstUserId(String userId) {
        if (StringUtils.isBlank(userId)) {
            throw new AppBusinessException("部门干部部长或主管不存在");
        }
        return userId.split(",")[0];
    }

    @Override
    public List<SdNoticeRecord> createOfferWorkerApproval(TbOfferWorker offerWorker, String approvalNote, Integer approvalType, String sendMailFlag) {
        List<SdNoticeRecord> result = new ArrayList<>();
        String content = "";
        String title = "";
        String workerId = offerWorker.getWorkerId();
        String workerName = offerWorker.getWorkerName();
        String workerNameAndId = workerName + "/" + workerId;
        String email = offerWorker.getEmail();
        String deptNameChain = offerWorker.getDeptNameChain();
        String workCity = offerWorker.getWorkCity();
        if (offerWorker.getPlanReportDate() == null && approvalType == 1) {
            throw new AppBusinessException("计划入职日期没有填写");
        }
        String planDateStr = offerWorker.getPlanReportDate() == null ? "" : DateUtil.getDateStr(offerWorker.getPlanReportDate());
        Map<String, String> map = new HashMap<>();
        if (!StringUtils.isEmpty(sendMailFlag) && BusiEnumDefine.NOTICE_MAIL_SEND_YES.equals(sendMailFlag)) {
                map = iSdDeptService.getBpAndContactorByDeptNameChain(deptNameChain, workCity);
        }
        String copyEmail = map.get("emails");
        if (approvalType == 1) {
            //您好，您登记的入职信息已经审核通过，请在{计划入职日期} 携带相关证件材料按时报到，我们期待您的加入。
            SdEmailTemplate template = emailTemplateService.getById("APPROVAL_WORKER_DATA_TYPE_1");
            title = template.getEmailTemplateTitle();
            content = template.getEmailTemplateContent();
            content = content.replace("{计划入职日期}", planDateStr);

            //您好！如下新员工的入职资料已经审核通过，您可登录新员工系统，查看相关预备员工的资料信息。
            //{预备员工信息：{员工姓名/工号} 预计报到日期：{计划入职日期} 计划入职部门：{}；...}
            //newreg.h3c.com
            SdEmailTemplate cardEmail = emailTemplateService.getById("APPROVAL_WORKER_DATA_CARD_EMAIL");
            String templateTitle = cardEmail.getEmailTemplateTitle();
            String templateContent = cardEmail.getEmailTemplateContent();
            templateContent = templateContent.replace("{员工姓名/工号}", workerNameAndId)
                    .replace("{计划入职日期}", planDateStr).replace("{部门名称}", deptNameChain);
            SdNoticeRecord noticeRecord = createEmailNoticeRecord("-1", workerId, workerName, email, title, content, "");
            result.add(noticeRecord);

            SdEmailTemplate emailTemplate4 = emailTemplateService.getById("APPROVAL_WORKER_DATA_TYPE_4");
            String emailTitle = emailTemplate4.getEmailTemplateTitle();
            String emailContent = emailTemplate4.getEmailTemplateContent();
            emailContent = emailContent.replace("{姓名/工号}", workerNameAndId)
                    .replace("{预计报到日期}", planDateStr)
                    .replace("{计划报到部门}", deptNameChain);
            SdNoticeRecord noticeRecordToN = createEmailNoticeRecord("-1", workerId, workerName, copyEmail, emailTitle, emailContent, "");
            result.add(noticeRecordToN);

            //卡证科邮件
            String userId = iSdUserService.getUserIdByRoleId(BusiEnumDefine.USER_ROLE_CARD_DEPT);
            if (StringUtils.isBlank(userId)) {
                throw new AppBusinessException("找不到卡证科管理员");
            }
            Map<String, String> cardMap = iSdDeptService.getWorkerMap(userId);
            SdNoticeRecord cardNoticeRecord = createEmailNoticeRecord("-1", cardMap.get("ids"), cardMap.get("names"),
                    cardMap.get("emails"), templateTitle, templateContent, "");
            result.add(cardNoticeRecord);
        } else if (approvalType == 2) {
            //您好，您填写的入职信息由于{审核原因}审核未通过，请登录以下链接完善或更新您的信息，我们期待您的加入。newreg.h3c.com
            SdEmailTemplate template = emailTemplateService.getById("APPROVAL_WORKER_DATA_TYPE_2");
            title = template.getEmailTemplateTitle();
            content = template.getEmailTemplateContent();
            content = workerName + content.replace("{审核原因}", "“" + approvalNote + "”");
            SdNoticeRecord noticeRecord = createEmailNoticeRecord("-1", workerId, workerName, email, title, content, copyEmail);
            result.add(noticeRecord);
        } else {
            //BusiEnumDefine.NOTICE_MAIL_SEND_YES.equals(sendMailFlag)即主动点击取消报道  否则为定时任务取消报道，不发消息
            if (!StringUtils.isEmpty(sendMailFlag) && BusiEnumDefine.NOTICE_MAIL_SEND_YES.equals(sendMailFlag)) {
                String sscDeptManagerId = iSdDeptService.getSscDeptManagerId(deptNameChain);
                String bpId = iSdDeptService.getBpByDeptNameChain(deptNameChain);
                String contactor = iSdDeptService.getContactorByDeptNameChain(deptNameChain, workCity);
                Map<String, String> contactorMap = iSdDeptService.getWorkerMap(contactor + "," + sscDeptManagerId + "," + bpId);
                email = contactorMap.get("emails");
                workerId = contactorMap.get("ids");
                workerName = contactorMap.get("names");
                copyEmail = "";
                String idAndName = commService.getLoginUserIdAndName();
                //您好，如下预备员工已被{操作人}取消报到，原因是：XXXX；
                //{预备员工信息姓名/工号 计划报到日期：2022-06-22 计划报到部门：信息技术部/AI及中台部/数据平台部；...}
                SdEmailTemplate template = emailTemplateService.getById("APPROVAL_WORKER_DATA_TYPE_3");
                title = template.getEmailTemplateTitle();
                content = template.getEmailTemplateContent();
                content = content.replace("{审核原因}", approvalNote)
                        .replace("{操作人}", idAndName)
                        .replace("{员工姓名/工号}", workerNameAndId)
                        .replace("{计划入职日期}", planDateStr)
                        .replace("{计划报到部门}", deptNameChain);

                SdNoticeRecord noticeRecord = createEmailNoticeRecord("-1", workerId, workerName, email, title, content, "");

                result.add(noticeRecord);
            }

            sapOfferWorkerCancellation(offerWorker);

            offerWorkerCancellation(offerWorker, sendMailFlag);
        }

        if (approvalType == 1 || approvalType == 2) {
            SdNoticeRecord smsNoticeRecord = createSmsNoticeRecord(workerId, workerName, offerWorker.getPhoneNo(), title, content);
            result.add(smsNoticeRecord);
        }
        return result;
    }

    public void sapOfferWorkerCancellation(TbOfferWorker offerWorker) {
        try {
            log.info("I_PERNR: {}", offerWorker.getWorkerId());
            rfcManager.connect();
            JCoDestination destination = rfcManager.getDestination();
            JCoFunction function = rfcManager.getFunction(destination, "ZFM_YBYG_QXBD");//调用SAP接口
            JCoParameterList importParameter = function.getImportParameterList();
            importParameter.setValue("I_PERNR", offerWorker.getWorkerId());

            function.execute(destination);
            JCoParameterList exportParameterList = function.getExportParameterList();
            sdRequestRecordService.addReqRecord(offerWorker.getWorkerId(), RequestEnum.取消报道.getName(), RequestEnum.取消报道.getUrl(), importParameter.toXML(), exportParameterList.toXML());
            JCoStructure aReturn = exportParameterList.getStructure("RETURN");
            String resCode = aReturn.getString("TYPE");
            if (!"S".equals(resCode)) {
                String message = aReturn.getString("MESSAGE");
                if (!(message.contains("不再在公司") || (message.contains("对于信息类型记录的开始日期,职位") && message.contains("无效")))) {
                    throw new AppBusinessException("sap预备员工取消报到失败：" + message);
                }
            }
        } catch (Exception e) {
            if (e instanceof AppBusinessException) {
                throw (AppBusinessException) e;
            }
            throw new AppBusinessException("sap预备员工取消报到异常");
        }
    }

    /**
     * 取消入职通知预备员工
     * @param offerWorker 预备员工信息
     * @param sendMailFlag 发送邮件标志  1 发送
     */
    public void offerWorkerCancellation(TbOfferWorker offerWorker, String sendMailFlag) {
        beiSenService.syncWorkerStatusToBeiSen(offerWorker);
        //BusiEnumDefine.NOTICE_MAIL_SEND_YES.equals(sendMailFlag)即主动点击取消报道  否则为定时任务取消报道，不发消息
        if (!StringUtils.isEmpty(sendMailFlag) && BusiEnumDefine.NOTICE_MAIL_SEND_YES.equals(sendMailFlag)) {
            //{员工姓名}您好：
            //经您本人确认，现已取消入职报到。感谢您对新华三的关注，期待下次合作！
            SdEmailTemplate emailTemplate = emailTemplateService.getById("OFFER_WORKER_CANCELLATION");
            String templateContent = emailTemplate.getEmailTemplateContent();
            String templateTitle = emailTemplate.getEmailTemplateTitle();
            templateContent = templateContent.replace("{员工姓名}", offerWorker.getWorkerName());
            SdNoticeRecord emailNoticeRecord = createEmailNoticeRecord("-1", offerWorker.getWorkerId(),
                    offerWorker.getWorkerName(), offerWorker.getEmail(), templateTitle, templateContent, "");
            SdNoticeRecord smsRecord = createSmsNoticeRecord(offerWorker.getWorkerId(), offerWorker.getWorkerName(),
                    offerWorker.getPhoneNo(), templateTitle, templateContent);
            asyncSendMessage.sendMessage(Arrays.asList(emailNoticeRecord, smsRecord));
        }
    }


    private SdNoticeRecord createEntity(String flowId, String workerId, String emailCode, String copyEmail) {
        SdAllWorker worker = commService.getAllWorkerDoFromLocalCache(workerId);
        if (worker == null) {
            throw new AppBusinessException("审核人没有找到 " + workerId);
        }
        SdEmailTemplate emailTemplate = emailTemplateService.getById(emailCode);
        if (emailTemplate == null) {
            throw new AppBusinessException("邮件模板没有找到 " + emailCode);
        }

        SdNoticeRecord sdNoticeRecord = new SdNoticeRecord();
        sdNoticeRecord.setNoticeId(IdWorker.nextId() + "");
        sdNoticeRecord.setFlowId(flowId);
        sdNoticeRecord.setApplyUserId(commService.getLoginUserId());
        sdNoticeRecord.setNoticeType(BusiEnumDefine.NOTICE_TYPE_EMAIL);
        sdNoticeRecord.setTargetId(workerId);
        sdNoticeRecord.setTargetName(worker.getWorkerName());
        sdNoticeRecord.setTargetEmail(worker.getEmail());
        sdNoticeRecord.setNoticeTitle(emailTemplate.getEmailTemplateTitle());
        sdNoticeRecord.setNoticeContent(emailTemplate.getEmailTemplateContent());
        sdNoticeRecord.setCreateTime(new Date());
        sdNoticeRecord.setCopyToEmail(copyEmail);
        return sdNoticeRecord;
    }

    @Override
    public SdNoticeRecord createEmailNoticeRecord(String flowId, String workerId, String workerName, String email,
                                             String title, String content, String copyEmail) {
        SdNoticeRecord sdNoticeRecord = new SdNoticeRecord();
        sdNoticeRecord.setNoticeId(IdWorker.nextId() + "");
        sdNoticeRecord.setFlowId(flowId);
        sdNoticeRecord.setApplyUserId(commService.getLoginUserIdWithNoException());
        sdNoticeRecord.setNoticeType(BusiEnumDefine.NOTICE_TYPE_EMAIL);
        sdNoticeRecord.setTargetId(workerId);
        sdNoticeRecord.setTargetName(workerName);
        sdNoticeRecord.setTargetEmail(email);
        sdNoticeRecord.setNoticeTitle(title);
        sdNoticeRecord.setNoticeContent(content);
        sdNoticeRecord.setCreateTime(new Date());
        sdNoticeRecord.setCopyToEmail(copyEmail);
        return sdNoticeRecord;
    }

    @Override
    public SdNoticeRecord createEmailNoticeRecord(String workerId, String workerName, String email, String title, String content) {
        return createEmailNoticeRecord("-1", workerId, workerName, email, title, content, "");
    }

    @Override
    public SdNoticeRecord createQwNoticeRecord(String workerId, String workerName, String title, String content) {
        SdNoticeRecord qwNoticeRecord = new SdNoticeRecord();
        qwNoticeRecord.setNoticeId(IdWorker.nextId() + "");
        qwNoticeRecord.setFlowId("-1");
        qwNoticeRecord.setApplyUserId(commService.getLoginUserIdWithNoException());
        qwNoticeRecord.setNoticeType(BusiEnumDefine.NOTICE_TYPE_QW);
        qwNoticeRecord.setTargetId(workerId);
        qwNoticeRecord.setTargetName(workerName);
        qwNoticeRecord.setNoticeTitle(title);
        qwNoticeRecord.setNoticeContent(content);
        qwNoticeRecord.setCreateTime(new Date());
        return qwNoticeRecord;
    }

    @Override
    public SdNoticeRecord createSmsNoticeRecord(String workerId, String workerName, String phoneNo, String title, String content) {
        SdNoticeRecord smsNoticeRecord = new SdNoticeRecord();
        smsNoticeRecord.setNoticeId(IdWorker.nextId() + "");
        smsNoticeRecord.setFlowId("-1");
        smsNoticeRecord.setApplyUserId(commService.getLoginUserIdWithNoException());
        smsNoticeRecord.setNoticeType(BusiEnumDefine.NOTICE_TYPE_SMS);
        smsNoticeRecord.setTargetId(workerId);
        smsNoticeRecord.setTargetName(workerName);
        smsNoticeRecord.setTargetPhone(phoneNo);
        smsNoticeRecord.setNoticeTitle(title);
        smsNoticeRecord.setNoticeContent(Jsoup.parse(content).text());
        smsNoticeRecord.setCreateTime(new Date());
        return smsNoticeRecord;
    }

    public SdNoticeRecord createMailRecord(String applyUserId, String targetId, String targetName, String targetEmail, String title, String content) {
        SdNoticeRecord notice = new SdNoticeRecord();
        notice.setNoticeId(IdWorker.nextId() + "");
        notice.setFlowId("-1");
        notice.setApplyUserId(applyUserId);
        notice.setNoticeType(BusiEnumDefine.NOTICE_TYPE_EMAIL);
        notice.setTargetId(targetId);
        notice.setTargetName(targetName);
        notice.setTargetEmail(targetEmail);
        notice.setNoticeTitle(title);
        notice.setNoticeContent(content);
        notice.setCreateTime(new Date());
        return notice;
    }
}
